package com.michael.demos.base.base.java8.optional;


import java.util.Optional;

/**
 * Optional 使用
 * Optional 用于解决NullException代码处理的问题
 * Optional 一般用在返回值的封装上，可以减少 null 的判断，结合 stream 相关API构建流畅的代码
 *
 * @author Michael
 */
public class OptionalDemo1 {

    public static void main(String[] args) {

        // 空的Optional
        Optional<User> empty = Optional.empty();
        // empty.get()会产生 NoSuchElementException
        // System.out.println(empty.get());

        // of 如果传参为 null 会导致 NullException  TODO 确定参数不为 null 用 of()
        // Optional<User> opt1 = Optional.of(null);

        // ofNullable 传参为 null 不会导致 NullException   TODO 不确定参数是否为 null 用 ofNullable()
        Optional<User> opt2 = Optional.ofNullable(null);

        // Optional中是否有值
        if (opt2.isPresent()) {
            System.out.println(opt2.get());
        } else {
            System.out.println("opt2无值");
        }

        // Optional中有值才执行对应的lambda表达式的内容
        opt2.ifPresent(System.out::println);


        // 如果 user1 为 null,则使用 orElse 里面的参数赋值
        User user4 = Optional.ofNullable(getUser1()).orElse(getUser2());
        System.out.println(user4);

        // 如果 user3 不为 null,则忽略 orElse 里面的参数赋值
        User user5 = Optional.ofNullable(getUser3()).orElse(getUser2());
        System.out.println(user5);

        System.out.println("======================================1");

        // orElseGet 与 get行为类似  TODO 但是当这里的 user3 非空时 orElse 中调用的方法还是会运行
        Optional.ofNullable(getUser3()).orElseGet(() -> getUser2());
        System.out.println("======================================2");
        Optional.ofNullable(getUser3()).orElse(getUser2());

        System.out.println("======================================3");
        // orElseThrow 当参数为 null 时会抛出自定义异常
        Optional.ofNullable(getUser1()).orElseThrow(() -> new RuntimeException("大事不好了"));


    }

    public static User getUser1() {
        System.out.println("getUser1()");
        return null;
    }

    public static User getUser2() {
        User user2 = new User();
        user2.setId(2);
        user2.setName("Michael");
        System.out.println("getUser2()");
        return user2;
    }

    public static User getUser3() {
        User user3 = new User();
        user3.setId(3);
        user3.setName("Michael");
        System.out.println("getUser3()");
        return user3;
    }


}

class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

class User {

    private int id;
    private String name;
    private Address address;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // address 可能为 null
    public Optional<Address> getAddress() {
        return Optional.ofNullable(address);
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}